home *** CD-ROM | disk | FTP | other *** search
- //\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/
- //
- // Simple GWorld.c
- //
- // Simple demonstration of offscreen to onscreen blit.
- //
- // The application:
- //
- // o opens window and shows it onscreen
- // o creates an offscreen GWorld same size as window
- // o renders a rather ugly image offscreen
- // o hangs out in a simple even loop...
- // o blits the offscreen to the onscreen on update events
- // o any key-press activity quits the app
- // o NOTE: you can drag the window around. If you have
- // multiple monitors, try dragging the window so that
- // only one column of content-area pixels touches
- // another screen; observe that screen's color environment.
- //
- //
- // Among the concepts illustrated are:
- //
- // + creation of simple offscreen GWorlds
- // + offscreen to onscreen CopyBits
- // + drawing offscreen and blitting appears faster
- // than drawing straight to screen (change
- // kDraw2ScreenHack to TRUE to update directly
- // to the screen.)
- //
- // History:
- //
- // 950304 jb: Written
- //
- //\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/
-
-
- // __#Defines________________________________________________________________________
- #undef TRUE
- #define TRUE !0 //Apple defines TRUE == 1; let's define it as *all* bits on
- #define DEBUG TRUE
- #define kMainWindowResID 1000
- #define kAppColorTableResID 300 //rather ugly gray-orange palette
- #define kDraw2ScreenHack FALSE //if TRUE, update directly to screen; don't
- //blit from offscreen; if FALSE, do the
- //nice, offscreen draw and blit do-se-do
-
- // __#Headers________________________________________________________________________
- #include "Utils.h" //several nubile functions are available here
- #include <Palettes.h>
- #include <math.h> //for transcendental functions
- #include <QDOffscreen.h> //need this for GWorlds
-
- // __#Protos_________________________________________________________________________
- // __ Macros_________________________________________________________________________
- // __ Enums__________________________________________________________________________
- // __ Typedefs_______________________________________________________________________
- // __ Static Protos__________________________________________________________________
- static Boolean OpenMainWindow( void );
- static Boolean InitApp( void );
- static void QuitApp( void );
- static void EventLoop( void );
- static Boolean CreateSimpleGWorld( GWorldPtr *newOffscreen );
- static void RenderToOffWorld( void );
- static void DrawSwirls( void );
- static void UpdateScreen( void );
-
- // __ Extern Globals_________________________________________________________________
- OSErr gErr;
- Str32 gAppName;
- WindowPtr gMainWindow;
- CGrafPtr gMainPort;
- GDHandle gMainGDev;
- CTabHandle gOurColorTable;
- PaletteHandle gAppPalette;
- GWorldPtr gOurGWorld;
-
- // __ Static Globals_________________________________________________________________
- // __ Functions______________________________________________________________________
-
-
- //____ main __________________________________________________________________________
- //
- void main( void )
- {
- if (InitApp()) //Initialize managers, allocate global structures, etc…
- {
- EventLoop(); //Handle events until user quits
-
- QuitApp(); //dispose and release everything
- }
-
- }//main
-
-
- //____ InitApp __________________________________________________________________________
- //
- // Returns FALSE if there were any problems initializing
- //
- static Boolean InitApp( void )
- {
- ToolBoxInit();
-
- if (!EnviroCheck())
- return FALSE;
-
- GetAppName((char *)gAppName);
-
- if (!OpenMainWindow())
- return FALSE;
-
- if (!CreateSimpleGWorld( &gOurGWorld ))
- return FALSE;
-
- #if kDraw2ScreenHack == FALSE
- RenderToOffWorld();
- #endif
-
- return TRUE;
- }//InitApp
-
-
- //____ QuitApp __________________________________________________________________________
- //
- // Dispose of and release anything and everything
- //
- static void QuitApp( void )
- {
- if(NULL != gMainWindow)
- DisposeWindow(gMainWindow);
- if(NULL != gOurColorTable)
- DisposeCTable(gOurColorTable);
- if (NULL != gOurGWorld)
- DisposeGWorld(gOurGWorld);
- }//QuitApp
-
-
- //____ OpenMainWindow __________________________________________________________________________
- //
- // Open our window, install palette built from a resource CTable.
- // provided by the System.
- //
- static Boolean OpenMainWindow( void )
- {
- CTabHandle tempColorTable;
-
- // create and show the window
- gMainWindow = GetNewCWindow( kMainWindowResID, ( Ptr )NULL, ( WindowPtr ) -1 );
- if (NULL == gMainWindow)
- return FALSE;
- ShowWindow( gMainWindow );
- SetPort( gMainWindow );
- SetWTitle( gMainWindow,gAppName );
-
- GetGWorld( &gMainPort, &gMainGDev ); //save this info for later convenience
-
- tempColorTable = GetCTable( kAppColorTableResID );
- mAssert(NULL != tempColorTable);
- if (NULL == tempColorTable)
- return FALSE;
-
- gAppPalette = NewPalette( 256, tempColorTable, pmTolerant + pmExplicit, 0x0000 );
- NSetPalette( gMainWindow, gAppPalette, pmFgUpdates );
-
- return TRUE;
- }//OpenMainWindow
-
-
- //____ EventLoop __________________________________________________________________________
- //
- // Nifty function shows off some ways to do Palette Animation
- //
- // Returns void
- //
- static void EventLoop( void )
- {
- Boolean done;
- EventRecord theEvent;
- short thePart;
- WindowPtr whichWin;
- RgnHandle theGrayRgn;
- Rect grayRgnLimitRect;
-
- theGrayRgn = GetGrayRgn(); //get region of all active screens (minus menu bar)
- grayRgnLimitRect = (**theGrayRgn).rgnBBox;
-
- done = FALSE;
- while (!done)
- {
- if(WaitNextEvent(everyEvent, &theEvent, 0L, 0L))
- {
- switch (theEvent.what)
- {
- case mouseDown:
- thePart = FindWindow( theEvent.where, &whichWin );
- if (whichWin == gMainWindow)
- {
- if ((inDrag == thePart) || (inContent == thePart))
- {
- DragWindow( gMainWindow, theEvent.where, &grayRgnLimitRect);
- }
- }
- break;//mouseDown
-
- case keyDown:
- done = TRUE;
- break;
-
- case updateEvt:
- if ((WindowPtr) theEvent.message == gMainWindow)
- {
- BeginUpdate(gMainWindow);
- UpdateScreen();
- EndUpdate(gMainWindow);
- }
- break;
- }//switch (theEvent.what)
- }//if WaitNextEvent
-
- }//while
-
- }//EventLoop
-
-
-
- //____ CreateSimpleGWorld __________________________________________________________________________
- //
- // Makes an offscreen GWorld using current port and device as a template.
- // Returns TRUE if offscreen was created, FALSE if there was a problem
- //
- static Boolean CreateSimpleGWorld( GWorldPtr *newOffscreen )
- {
- #define kNoCTable NULL
- #define kDeepestIntersectingDepth 0
-
- Boolean returnMe = FALSE;
- CGrafPtr curPort;
- GDHandle curDevice;
- Rect globalRect;
- GWorldFlags ourGWFlags;
-
- GetGWorld(&curPort, &curDevice);
-
- *newOffscreen = NULL; //just in case NewGWorld fails
-
- ourGWFlags = noNewDevice; //ourGWFlags describe certain options to NewGWorld.
- //noNewDevice tells NewGWorld not to make a new
- //GDevice for this GWorld. Instead, it will use the
- //depth and Color Table of our curDevice (if the depth
- //parameter is zero, then the deepest device intersecting
- //the passed rectangle is used.)
-
- //get rectangle defining current port's interior, translate it
- //into global coordinates.
- globalRect = curPort->portRect;
- LocalToGlobal(&mTopLeft(globalRect));
- LocalToGlobal(&mBotRight(globalRect));
-
- gErr = NewGWorld( newOffscreen, kDeepestIntersectingDepth,
- &globalRect, kNoCTable, curDevice, ourGWFlags);
- mAssert(gErr == noErr);
- if (noErr != gErr)
- goto Xit;
-
- returnMe = TRUE;
- Xit:
- SetGWorld(curPort, curDevice);
- return(returnMe);
- }//CreateSimpleGWorld
-
-
- //____ RenderToOffWorld __________________________________________________________________________
- //
- // Does time-consuming draw to offscreen world
- //
- static void RenderToOffWorld( void )
- {
- PixMapHandle offPix;
-
- mAssert(NULL != gOurGWorld);
- if (NULL == gOurGWorld)
- goto Xit;
-
- SetGWorld(gMainPort, gMainGDev); //point to our window
- MoveTo(8, 24);
- DrawString("\pRendering Offscreen"); //let user know what's going on
-
- offPix = GetGWorldPixMap(gOurGWorld); //use GetGWorldPixMap to get PixMap of
- //an offscreen GWorld; dereferencing
- //the GWorld pointer for it is a no-no.
- mAssert(NULL != offPix);
- if (NULL == offPix)
- goto Xit;
-
- if(LockPixels(offPix)) //Lock pixels before drawing
- {
- SetGWorld( gOurGWorld, NULL ); //SetGWorld ignores GDevice handle if port
- //passed is a GWorldPtr; it uses the
- //GDevice the port is attached to
-
- DrawSwirls(); //draw those whacky swirls…
-
- UnlockPixels(offPix);
- }
- Xit:
- SetGWorld(gMainPort, gMainGDev); //point to our window
- return;
- }//RenderToOffWorld
-
-
-
-
-
- //____ DrawSwirls __________________________________________________________________________
- //
- // Draws silly swirls. Doesn't care what port it's pointed at, so make sure you've already
- // pointed it at a valid port.
- //
- static void DrawSwirls( void )
- {
- #define kDotFactor 4
- #define mHalfRect (theRadius / kDotFactor)
- #define kNumSwirls 4
- #define kNumSteps 254
- #define mThetaStepSize (6.283 / kNumSteps) //how far around our circle to go
- #define kRadiusStep 1
-
- short step;
- short x, y, cenX, cenY;
- double theta;
- Rect aRect;
- short theRadius;
- RGBColor theRGB;
- short swirlNumber;
-
- cenX = qd.thePort->portRect.right / 2;
- cenY = qd.thePort->portRect.bottom / 2;
-
- RGBForeColor(&blackRGB);
- RGBForeColor(&whiteRGB);
- EraseRect(&qd.thePort->portRect);
-
- for (swirlNumber = 0; swirlNumber < kNumSwirls; swirlNumber++)
- {
- theRadius = 0;
-
- for (step = 1, theta = (1.57 * swirlNumber); step <= kNumSteps; step++)
- {
- theta += mThetaStepSize;
-
- x = cenX + theRadius * cos(theta);
- y = cenY - theRadius * sin(theta);
-
- theRGB = (**gAppPalette).pmInfo[step].ciRGB;
- RGBForeColor(&theRGB);
-
- if (kDotFactor < theRadius)
- SetRect(&aRect, x - mHalfRect, y - mHalfRect, x + mHalfRect, y + mHalfRect);
- else
- SetRect(&aRect, x, y, x + 1, y + 1);
-
- PaintOval(&aRect);
-
- theRadius += kRadiusStep;
-
- }
- }
-
- }//DrawSwirls
-
-
- //____ UpdateScreen __________________________________________________________________________
- //
- // Blits offscreen to onscreen.
- //
- static void UpdateScreen( void )
- {
- CGrafPtr oldPort;
- GDHandle oldGDev;
- PixMapHandle offPix;
-
- GetGWorld(&oldPort, &oldGDev);
-
- SetGWorld(gMainPort, gMainGDev); //point to our window
-
- #if kDraw2ScreenHack == TRUE
- DrawSwirls();
- goto Xit;
- #endif
-
- if (NULL == gOurGWorld)
- {
- MoveTo(8, 40);
- DrawString("\pNo Offworld to Blit");
- goto Xit;
- }
-
- offPix = GetGWorldPixMap(gOurGWorld); //get base address of our offscreen's PixMap
- mAssert(NULL != offPix);
- if (NULL == offPix)
- goto Xit;
-
- //Finally, blit offscreen to onscreen
- if(LockPixels(offPix)) //Lock pixels before drawing
- {
- RGBForeColor(&blackRGB); //ALWAYS set fore and back colors
- RGBBackColor(&whiteRGB); //to black and white, unless you
- //want to colorize the blit
-
- // ctSeed slam: Force the color table seeds to be identical for speed
- ( *( ( *( offPix ) )->pmTable ) )->ctSeed =
- ( *( ( *( ( *gMainGDev )->gdPMap ) )->pmTable ) )->ctSeed;
-
- CopyBits( (BitMap *)*offPix, &((GrafPtr)gMainPort)->portBits,
- &gMainPort->portRect, &gMainPort->portRect,
- srcCopy,NULL);
- UnlockPixels(offPix);
- }
-
- Xit:
- SetGWorld(oldPort, oldGDev);
- return;
- }//UpdateScreen
-